using CCWin; // 引用CCWin皮肤库
using System; // 引用系统基础命名空间
using System.Collections.Generic; // 引用泛型集合命名空间
using System.ComponentModel; // 引用组件模型命名空间
using System.Data; // 引用数据相关命名空间
using System.Drawing; // 引用绘图相关命名空间
using System.Text; // 引用文本处理相关命名空间
using System.Windows.Forms; // 引用WinForms命名空间
using System.Net.Http; // 引用HTTP客户端命名空间
using Newtonsoft.Json; // 引用Newtonsoft.Json序列化命名空间
using System.Threading.Tasks; // 引用异步任务命名空间
using System.Configuration; // 引用配置管理命名空间
using Mes.Production.Models;
using Mes.Production.Config;
using Mes.Production.Common;
using System.Globalization;
using Mes; // 使用 HttpClientHelper

namespace Mes.Production
{
    /// <summary>
    /// 新增生产订单窗体
    /// </summary>
    public partial class AddProductionOrder : Form
    {
        private int seqCounter = 0; // 序号计数器
        private DateTimePicker gridDatePicker; // 用于DataGridView内编辑交付日期的日期控件
        // 已切换为使用 HttpClientHelper

        public AddProductionOrder() // 构造函数
        {
            InitializeComponent(); // 初始化组件（由设计器生成的控件初始化）
            // 使用 HttpClientHelper 统一调用，无需在此初始化 HttpClient
        }

        private void AddProductionOrder_Load(object sender, EventArgs e) // 窗体加载事件
        {
            // 设置窗体为全屏状态
            this.WindowState = FormWindowState.Maximized;

            BindOrderSource(); // 调用方法绑定订单来源下拉框数据
            InitFinishedProductGrid(); // 初始化成品信息表格的列编辑属性
            GenerateOrderNumber(); // 自动生成订单编号

            // 注册与日期编辑相关的事件
            dgvFinishedProducts.CellClick += DgvFinishedProducts_CellClick; // 单元格点击时处理日期编辑
            dgvFinishedProducts.Scroll += DgvFinishedProducts_Scroll; // 滚动时隐藏日期控件
            dgvFinishedProducts.ColumnWidthChanged += DgvFinishedProducts_ColumnWidthChanged; // 列宽变化时隐藏
            dgvFinishedProducts.SizeChanged += DgvFinishedProducts_SizeChanged; // 表格尺寸变化时隐藏

            // 注册窗体大小改变事件
            this.SizeChanged += AddProductionOrder_SizeChanged;

            // 窗体加载完成后，延迟执行一次居中调整（确保所有控件都已初始化）
            this.BeginInvoke(new Action(() => CenterBasicInfoControls()));
        }

        /// <summary>
        /// 窗体大小改变事件，调整控件居中位置
        /// </summary>
        private void AddProductionOrder_SizeChanged(object sender, EventArgs e)
        {
            CenterBasicInfoControls();
        }

        /// <summary>
        /// 调整基本信息区域控件的居中位置
        /// </summary>
        private void CenterBasicInfoControls()
        {
            try
            {
                // 计算基本信息区域的中心位置
                int groupBoxWidth = groupBox1.Width;
                int groupBoxHeight = groupBox1.Height;

                // 第一行控件（订单编号、重新生成按钮、订单来源）
                int firstRowY = 48;
                int leftMargin = 50; // 左边距
                int rightMargin = 50; // 右边距
                int availableWidth = groupBoxWidth - leftMargin - rightMargin;

                // 计算合理的控件间距
                int orderNumberWidth = lblOrderNumber.Width + txtOrderNumber.Width + btnRegenerateOrderNumber.Width + 20; // 订单编号区域总宽度
                int orderSourceWidth = lblOrderSource.Width + cobOrderSource.Width + 10; // 订单来源区域总宽度
                int totalControlsWidth = orderNumberWidth + orderSourceWidth; // 所有控件总宽度

                // 声明变量，确保在所有代码路径中都能访问
                int startX = leftMargin; // 默认值
                bool isCentered = false;

                // 如果控件总宽度小于可用宽度，则居中分布；否则保持最小间距
                if (totalControlsWidth < availableWidth)
                {
                    // 居中分布
                    int centerX = groupBoxWidth / 2;
                    startX = centerX - totalControlsWidth / 2;
                    isCentered = true;

                    // 订单编号标签和文本框（左对齐）
                    lblOrderNumber.Location = new System.Drawing.Point(startX, firstRowY);
                    txtOrderNumber.Location = new System.Drawing.Point(startX + lblOrderNumber.Width + 10, firstRowY);

                    // 重新生成按钮（订单编号文本框右侧）
                    btnRegenerateOrderNumber.Location = new System.Drawing.Point(txtOrderNumber.Location.X + txtOrderNumber.Width + 10, firstRowY);

                    // 订单来源标签和下拉框（订单编号区域右侧）
                    int orderSourceX = startX + orderNumberWidth + 50; // 50像素的间距
                    cobOrderSource.Location = new System.Drawing.Point(orderSourceX + lblOrderSource.Width + 10, firstRowY);
                    lblOrderSource.Location = new System.Drawing.Point(orderSourceX, firstRowY);
                }
                else
                {
                    // 保持最小间距分布
                    startX = leftMargin;
                    isCentered = false;

                    lblOrderNumber.Location = new System.Drawing.Point(startX, firstRowY);
                    txtOrderNumber.Location = new System.Drawing.Point(startX + lblOrderNumber.Width + 10, firstRowY);

                    btnRegenerateOrderNumber.Location = new System.Drawing.Point(txtOrderNumber.Location.X + txtOrderNumber.Width + 10, firstRowY);

                    // 订单来源标签和下拉框（右对齐）
                    int orderSourceX = groupBoxWidth - rightMargin - cobOrderSource.Width;
                    cobOrderSource.Location = new System.Drawing.Point(orderSourceX, firstRowY);
                    lblOrderSource.Location = new System.Drawing.Point(orderSourceX - lblOrderSource.Width - 10, firstRowY);
                }

                // 第二行控件（备注）
                int secondRowY = 113;

                if (isCentered)
                {
                    // 备注区域也居中显示
                    int remarksLabelWidth = lblRemarks.Width;

                    // 计算备注文本框的宽度，使其右边缘与订单来源选择框右边缘对齐
                    int orderSourceRightEdge = startX + orderNumberWidth + 50 + lblOrderSource.Width + 10 + cobOrderSource.Width;
                    int remarksTextBoxWidth = orderSourceRightEdge - (startX + remarksLabelWidth + 10);

                    // 确保文本框宽度不会过小
                    remarksTextBoxWidth = Math.Max(remarksTextBoxWidth, 300);

                    lblRemarks.Location = new System.Drawing.Point(startX, secondRowY);
                    txtRemarks.Location = new System.Drawing.Point(startX + remarksLabelWidth + 10, secondRowY);
                    txtRemarks.Width = remarksTextBoxWidth;
                }
                else
                {
                    // 保持最小间距分布
                    lblRemarks.Location = new System.Drawing.Point(leftMargin, secondRowY);
                    txtRemarks.Location = new System.Drawing.Point(leftMargin + lblRemarks.Width + 10, secondRowY);
                    txtRemarks.Width = groupBoxWidth - leftMargin - rightMargin - lblRemarks.Width - 20;
                }
            }
            catch (Exception ex)
            {
                // 如果调整失败，记录错误但不影响程序运行
                System.Diagnostics.Debug.WriteLine(string.Format("调整控件居中位置失败: {0}", ex.Message));
            }
        }

        /// <summary>
        /// 自动生成订单编号
        /// 生成规则：DDH + 当前年月日 + 毫秒
        /// </summary>
        private void GenerateOrderNumber()
        {
            try
            {
                var now = DateTime.Now;
                var orderNumber = string.Format("DDH{0:yyyyMMdd}{1:D3}", now, now.Millisecond);
                txtOrderNumber.Text = orderNumber;
                txtOrderNumber.ReadOnly = true; // 设置为只读，防止用户修改
            }
            catch (Exception ex)
            {
                // 如果生成失败，记录错误但不影响程序运行
                System.Diagnostics.Debug.WriteLine(string.Format("生成订单编号失败: {0}", ex.Message));
            }
        }

        /// <summary>
        /// 重新生成订单编号
        /// </summary>
        private void RegenerateOrderNumber()
        {
            try
            {
                var now = DateTime.Now;
                var orderNumber = string.Format("DDH{0:yyyyMMdd}{1:D3}", now, now.Millisecond);
                txtOrderNumber.Text = orderNumber;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(string.Format("重新生成订单编号失败: {0}", ex.Message));
            }
        }

        /// <summary>
        /// 重新生成订单编号按钮点击事件
        /// </summary>
        private void btnRegenerateOrderNumber_Click(object sender, EventArgs e)
        {
            RegenerateOrderNumber();
        }

        /// <summary> // 说明
        /// 初始化成品信息表格（设置可编辑列等） // 功能描述
        /// </summary> // 结束
        private void InitFinishedProductGrid() // 初始化表格设置
        {
            // 只允许编辑计划产量与交付日期
            if (dgvFinishedProducts.Columns.Count > 0) // 确保列已经存在
            {
                dgvFinishedProducts.ReadOnly = false; // 整体可编辑
                // 非编辑列设置为只读
                dgvFinishedProducts.Columns["colSeq"].ReadOnly = true; // 序号只读
                dgvFinishedProducts.Columns["colIdHidden"].ReadOnly = true; // 隐藏物料ID只读
                dgvFinishedProducts.Columns["colFinishedNo"].ReadOnly = true; // 成品编号只读
                dgvFinishedProducts.Columns["colFinishedName"].ReadOnly = true; // 成品名称只读
                dgvFinishedProducts.Columns["colSpecificationModel"].ReadOnly = true; // 规格型号只读
                dgvFinishedProducts.Columns["colUnit"].ReadOnly = true; // 单位只读
                // 可编辑列
                dgvFinishedProducts.Columns["colPlanQty"].ReadOnly = false; // 计划产量可编辑
                dgvFinishedProducts.Columns["colDeliveryDate"].ReadOnly = false; // 交付日期可编辑
                dgvFinishedProducts.Columns["colDeliveryDate"].DefaultCellStyle.Format = "yyyy-MM-dd"; // 日期显示格式
            }

            // 创建日期控件并添加到表格控件集合中（默认隐藏）
            gridDatePicker = new DateTimePicker // 初始化日期控件
            {
                Visible = false, // 初始隐藏
                Format = DateTimePickerFormat.Custom, // 使用自定义格式
                CustomFormat = "yyyy-MM-dd" // 自定义格式字符串
            };
            gridDatePicker.CloseUp += GridDatePicker_CloseUp; // 选择完成后提交
            gridDatePicker.ValueChanged += GridDatePicker_ValueChanged; // 值变化时更新单元格
            dgvFinishedProducts.Controls.Add(gridDatePicker); // 将日期控件加入表格
        }

        private void ShowDatePicker(Rectangle cellRect, DateTime init) // 在指定单元格区域显示日期控件
        {
            gridDatePicker.Bounds = cellRect; // 设置位置和大小
            gridDatePicker.Value = init; // 设置初始值
            gridDatePicker.Visible = true; // 显示控件
            gridDatePicker.BringToFront(); // 置顶
        }

        private void HideDatePicker() // 隐藏日期控件
        {
            if (gridDatePicker != null && gridDatePicker.Visible) // 若控件可见
            {
                gridDatePicker.Visible = false; // 隐藏
            }
        }

        private void DgvFinishedProducts_CellClick(object sender, DataGridViewCellEventArgs e) // 单元格点击事件
        {
            if (e.RowIndex >= 0 && dgvFinishedProducts.Columns[e.ColumnIndex].Name == "colDeliveryDate") // 点击交付日期列
            {
                var cell = dgvFinishedProducts.Rows[e.RowIndex].Cells[e.ColumnIndex]; // 获取当前单元格
                var rect = dgvFinishedProducts.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true); // 获取显示矩形
                DateTime init = DateTime.Now; // 默认日期
                if (cell.Value != null) // 若已有值
                {
                    DateTime.TryParse(cell.Value.ToString(), out init); // 尝试解析
                }
                ShowDatePicker(rect, init); // 展示日期控件
            }
            else // 其他列
            {
                HideDatePicker(); // 隐藏日期控件
            }
        }

        private void DgvFinishedProducts_Scroll(object sender, ScrollEventArgs e) { HideDatePicker(); } // 滚动隐藏日期控件
        private void DgvFinishedProducts_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e) { HideDatePicker(); } // 列宽变化隐藏
        private void DgvFinishedProducts_SizeChanged(object sender, EventArgs e) { HideDatePicker(); } // 尺寸变化隐藏

        private void GridDatePicker_ValueChanged(object sender, EventArgs e) // 日期值变更
        {
            if (dgvFinishedProducts.CurrentCell != null && dgvFinishedProducts.Columns[dgvFinishedProducts.CurrentCell.ColumnIndex].Name == "colDeliveryDate") // 确认是交付日期列
            {
                dgvFinishedProducts.CurrentCell.Value = gridDatePicker.Value.ToString("yyyy-MM-dd"); // 回写到单元格
            }
        }

        private void GridDatePicker_CloseUp(object sender, EventArgs e) // 日期控件关闭时
        {
            HideDatePicker(); // 隐藏日期控件
        }

        /// <summary> // 注释
        /// 绑定订单来源下拉框 // 功能
        /// </summary> // 结束
        private void BindOrderSource() // 绑定订单来源到下拉框
        {
            var orderSourceMap = new Dictionary<int, string> // 定义来源字典：Key为Id，Value为显示文本
            {
                { 0, "--请选择--" }, // 默认未选择项
                { 1, "手工录入" }, // 选项：手工录入
                { 2, "系统下发" }, // 选项：系统下发
                { 3, "APS调度" } // 选项：APS调度
            }; // 字典初始化结束

            cobOrderSource.DataSource = new BindingSource(orderSourceMap, null); // 将字典包装为BindingSource并绑定为数据源
            cobOrderSource.DisplayMember = "Value"; // 设置显示字段为字典的Value
            cobOrderSource.ValueMember = "Key"; // 设置实际值字段为字典的Key
            cobOrderSource.SelectedValue = 0; // 默认选中"--请选择--"
        }

        /// <summary> // 注释
        /// 获取当前选择的订单来源Id // 功能
        /// </summary> // 结束
        private int GetSelectedOrderSourceId() // 返回选中的来源Id
        {
            if (cobOrderSource.SelectedValue == null) // 没有选中值
            {
                return 0; // 返回0表示无效
            }
            int value; // 用于接收转换结果
            return int.TryParse(cobOrderSource.SelectedValue.ToString(), out value) ? value : 0; // 解析失败返回0
        }

        /// <summary> // 注释
        /// 添加成品：弹出选择成品列表窗口，支持多选，选择后回填行数据 // 功能
        /// </summary> // 结束
        private void btnAddFinishedProduct_Click(object sender, EventArgs e) // 点击"添加成品"
        {
            using (var dialog = new SelectMaterialDialog()) // 实例化选择成品对话框
            {
                if (dialog.ShowDialog(this) == DialogResult.OK && dialog.SelectedMaterials != null && dialog.SelectedMaterials.Count > 0) // 用户确认并有选择
                {
                    foreach (var m in dialog.SelectedMaterials) // 遍历所选成品
                    {
                        seqCounter++; // 序号自增
                        int rowIndex = dgvFinishedProducts.Rows.Add(); // 新增一行
                        var row = dgvFinishedProducts.Rows[rowIndex]; // 取得新行

                        // 回填选择的物料信息
                        row.Cells["colSeq"].Value = seqCounter; // 序号
                        row.Cells["colIdHidden"].Value = m.Id; // 隐藏物料ID
                        row.Cells["colFinishedNo"].Value = m.FinishedNo; // 成品编号
                        row.Cells["colFinishedName"].Value = m.FinishedName; // 成品名称
                        row.Cells["colSpecificationModel"].Value = m.SpecificationModel; // 规格型号
                        row.Cells["colUnit"].Value = m.Unit; // 单位
                        row.Cells["colPlanQty"].Value = 0; // 默认计划产量
                        row.Cells["colDeliveryDate"].Value = DateTime.Now.ToString("yyyy-MM-dd"); // 默认交付日期
                    }
                }
            }
        }

        /// <summary> // 注释
        /// 操作列点击：移除当前行 // 功能
        /// </summary> // 结束
        private void dgvFinishedProducts_CellContentClick(object sender, DataGridViewCellEventArgs e) // 表格操作列点击
        {
            if (e.RowIndex >= 0 && dgvFinishedProducts.Columns[e.ColumnIndex].Name == "colOperation") // 判断是否为操作列
            {
                dgvFinishedProducts.Rows.RemoveAt(e.RowIndex); // 删除行
            }
        }

        /// <summary> // 注释
        /// 确定（保存） // 功能
        /// </summary> // 结束
        private async void btnConfirm_Click(object sender, EventArgs e) // 点击"确定"
        {
            try
            {
                // 禁用按钮，防止重复提交
                btnConfirm.Enabled = false;
                btnConfirm.Text = "保存中...";
                Cursor = Cursors.WaitCursor;

                // 确保提交表格当前编辑值（用户可能未离开单元格就点击保存）
                try
                {
                    if (dgvFinishedProducts.IsCurrentCellInEditMode)
                    {
                        dgvFinishedProducts.CommitEdit(DataGridViewDataErrorContexts.Commit);
                    }
                    dgvFinishedProducts.EndEdit();
                }
                catch { }

                // 隐藏日期控件，确保已回写到单元格
                HideDatePicker();

                // 基础校验
                var orderNumber = (txtOrderNumber.Text ?? string.Empty).Trim(); // 订单编号
                if (orderNumber.Length == 0) // 编号为空
                {
                    MessageBox.Show("订单编号不能为空，请重新生成", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); // 提示
                    RegenerateOrderNumber(); // 重新生成订单编号
                    return; // 中断
                }

                var orderSourceId = GetSelectedOrderSourceId(); // 获取来源
                if (orderSourceId == 0) // 未选择来源
                {
                    MessageBox.Show("请选择订单来源", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); // 提示
                    cobOrderSource.DroppedDown = true; // 展开下拉
                    return; // 中断
                }

                // 校验表格数据
                if (dgvFinishedProducts.Rows.Count == 0) // 没有成品行
                {
                    MessageBox.Show("请添加至少一个成品项", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); // 提示
                    return; // 中断
                }

                // 构建生产订单项列表
                var productionOrderItems = new List<ProductionOrderItemDto>();
                foreach (DataGridViewRow row in dgvFinishedProducts.Rows) // 遍历行
                {
                    if (row.IsNewRow) continue; // 跳过占位行

                    // 校验计划产量
                    double qty; // 计划产量
                    if (row.Cells["colPlanQty"].Value == null || !double.TryParse(row.Cells["colPlanQty"].Value.ToString(), out qty) || qty < 0) // 校验
                    {
                        MessageBox.Show("计划产量必须为非负数字", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); // 提示
                        return; // 中断
                    }

                    // 校验交付日期（按固定格式解析）
                    DateTime dt; // 交付日期
                    var deliveryText = row.Cells["colDeliveryDate"].Value == null ? string.Empty : row.Cells["colDeliveryDate"].Value.ToString();
                    if (string.IsNullOrWhiteSpace(deliveryText) ||
                        !DateTime.TryParseExact(deliveryText, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt)) // 校验
                    {
                        MessageBox.Show("交付日期格式不正确", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); // 提示
                        return; // 中断
                    }

                    // 构建生产订单项（仅传后端所需字段）
                    var item = new ProductionOrderItemDto
                    {
                        MaterialId = Convert.ToInt32(row.Cells["colIdHidden"].Value),
                        PlannedQuantity = qty,
                        DeliveryDate = dt
                    };
                    productionOrderItems.Add(item);
                }

                var remarks = (txtRemarks.Text ?? string.Empty).Trim(); // 备注

                // 构建请求数据
                var requestData = new CreateProductionOrderRequest
                {
                    OrderNumber = orderNumber,
                    Remarks = remarks,
                    OrderSource = orderSourceId,
                    CreatorId = 0, // 暂时设为0，实际应该从用户登录信息获取
                    CreateTime = DateTime.Now,
                    ProductionOrderItem = productionOrderItems
                };

                // 调用API
                var result = await CreateProductionOrderAsync(requestData);
                // 根据后端规范判断：仅以 Code == 200 作为成功
                var isOk = result != null && result.Code == 200;
                if (isOk)
                {
                    // 提示优先级：Msg > 默认成功文案
                    var backendMsg = (result.Msg ?? string.Empty).Trim();
                    var successMsg = backendMsg.Length > 0 ? backendMsg : "新增成功";
                    MessageBox.Show(successMsg, "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    this.DialogResult = DialogResult.OK;
                    this.Close();
                }
                else
                {
                    // 提示优先级：Msg > 默认失败文案
                    var backendMsg = result != null ? (result.Msg ?? string.Empty).Trim() : string.Empty;
                    var errorMessage = backendMsg.Length > 0 ? backendMsg : "新增失败";
                    MessageBox.Show(errorMessage, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("创建生产订单时发生错误：{0}", ex.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                // 恢复按钮状态
                btnConfirm.Enabled = true;
                btnConfirm.Text = "确定";
                Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// 调用后端API创建生产订单
        /// </summary>
        /// <param name="request">请求数据</param>
        /// <returns>API响应结果</returns>
        private async Task<ApiResponse<int>> CreateProductionOrderAsync(CreateProductionOrderRequest request)
        {
            try
            {
                var apiUrl = ApiConfig.GetApiBaseUrl();
                var url = string.Format("{0}/api/ProductionOrder/CreateProductionOrder", apiUrl);
                // 使用统一的 HttpClientHelper.PostAsync<T>
                var parsed = await HttpClientHelper.PostAsync<ApiResponse<int>>(url, request, false);
                return parsed ?? new ApiResponse<int>
                {
                    Code = 500,
                    Msg = "请求失败，未返回数据"
                };
            }
            catch (TaskCanceledException)
            {
                return new ApiResponse<int>
                {
                    Success = false,
                    Message = "请求超时，请检查网络连接"
                };
            }
            catch (Exception ex)
            {
                return new ApiResponse<int>
                {
                    Success = false,
                    Message = string.Format("请求异常: {0}", ex.Message)
                };
            }
        }

        /// <summary>
        /// 关闭按钮点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClose_Click(object sender, EventArgs e)
        {
            // 设置对话框结果为取消并关闭窗体
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }
    }
}
